//go:build wireinject
// +build wireinject

package dproxy

import (
	"gitee.com/yysf-xin/dproxy/controller"
	"gitee.com/yysf-xin/dproxy/controller/proxyc"
	"gitee.com/yysf-xin/dproxy/controller/qrcode"
	"gitee.com/yysf-xin/dproxy/controller/spider"
	"gitee.com/yysf-xin/dproxy/controller/user"
	"gitee.com/yysf-xin/dproxy/pkg/app"
	"gitee.com/yysf-xin/dproxy/pkg/corn"
	"gitee.com/yysf-xin/dproxy/pkg/db"
	"gitee.com/yysf-xin/dproxy/pkg/svr"
	"gitee.com/yysf-xin/dproxy/pkg/turn"
	"github.com/google/wire"
	"github.com/soheilhy/cmux"
	"golang.org/x/net/proxy"
	"net"
	"net/http"
)

func useTr(r *proxyc.RouteControl) *http.Transport {
	return http.DefaultTransport.(*http.Transport)
}

func useDialer(r *proxyc.RouteControl) proxy.Dialer {
	return r
}

func useDirector(r *proxyc.RouteControl) svr.Director {
	return r
}
func useGroupChooser(r *proxyc.RouteControl) turn.GroupChooser {
	return r.ChooseServerId
}

func useConfigFile(config *app.Config) *app.ConfigFile {
	return &config.File
}
func useSsl(config *app.Config) *app.Ssl {
	return &config.File.Ssl
}

//var cfgSet = wire.NewSet(
//	app.NewConfigFile,
//)
//

var spiderSet = wire.NewSet(
	spider.NewProxySpider,
	spider.NewV2flay,
	wire.Struct(new(spider.Spider), "*"),
)

var serviceSet = wire.NewSet(
	app.NewServices,
	proxyc.NewLocalControl,
	proxyc.NewRouteControl,
	proxyc.NewSSHControl,
	proxyc.NewSocket5Control,
	useTr,
	useDialer,
	useDirector,
	useSsl,
	svr.NewProxy,
	proxyc.NewTunnelControl,
	useGroupChooser,
	proxyc.NewTurnControl,
	proxyc.NewProxyControl,
	wire.Struct(new(proxyc.ServerControl), "*"),
	user.NewUserControl,
	user.NewJwtAuthToken,
	corn.NewCornControl,
	NewCMux,
)

var toolsSet = wire.NewSet(
	//wire.Struct(new(qrcode.QrGenerator)),
	qrcode.NewQrGenerator,
	wire.Struct(new(controller.ToolsRoute), "*"),
)

var serverSet = wire.Struct(new(Server), "*")

func NewRoute() *controller.RouterConfig {
	return &controller.RouterConfig{}
}

func NewCMux(config *app.Config) (m cmux.CMux, err error) {
	l, err := net.Listen("tcp", config.File.Addr)
	if err == nil {
		m = cmux.New(l)
	}
	return
}

var controlSet = wire.Struct(new(controller.RouterConfig), "*")

func NewServer(cfg *app.Config) (*Server, error) {
	wire.Build(
		useConfigFile,
		db.DbSet,
		serviceSet,
		controlSet,
		spiderSet,
		toolsSet,
		serverSet)
	return &Server{}, nil
}
